home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / SizeableExp.C < prev    next >
C/C++ Source or Header  |  1992-05-05  |  4KB  |  204 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "SizeableExp.h"
  6.  
  7. #include "Class.h"
  8. #include "Command.h"
  9. #include "Collection.h"
  10. #include "Look.h"
  11. #include "Math.h"
  12.  
  13. //---- SplitMover --------------------------------------------------------------
  14.  
  15. class SplitMover: public Command {
  16.     SplitArea *sap;
  17.     Direction dir;
  18.     Point min, max;
  19. public:
  20.     SplitMover(SplitArea *sp, Direction d, Point mi, Point mx);
  21.     Command *TrackMouse(TrackPhase, Point, Point, Point);
  22.     void TrackConstrain(Point ap, Point pp, Point *np);
  23. };
  24.  
  25. SplitMover::SplitMover(SplitArea *sp, Direction d, Point mi, Point mx)
  26. {
  27.     sap= sp;
  28.     dir= d;
  29.     min= mi;
  30.     max= mx; 
  31.     SetType(eCmdTypeNoChange);
  32. }
  33.  
  34. Command *SplitMover::TrackMouse(TrackPhase tp, Point, Point pp, Point np)
  35. {
  36.     Point d= np-pp;
  37.     switch (tp) {
  38.     case eTrackMove:
  39.     GrSetCursor(eCrsMoveHand);
  40.     sap->Control(sap->GetId(), cPartChangeSplit, &d);
  41.     break;
  42.     
  43.     case eTrackRelease:
  44.     return gNoChanges;
  45.     default:
  46.     break;
  47.     }
  48.     return this;
  49. }
  50.     
  51. void SplitMover::TrackConstrain(Point ap, Point, Point *np)
  52. {
  53.     Point d= *np-ap;
  54.     if (dir == eVert)
  55.     np->y= ap.y+Math::Range(min.y, max.y, d.y);
  56.     else
  57.     np->x= ap.x+Math::Range(min.x, max.x, d.x);
  58. }
  59.  
  60. //---- SplitArea --------------------------------------------------------------
  61.  
  62. SplitArea::SplitArea(int id, Direction d) : VObject(id)
  63.     dir= d;
  64.     if (dir == eVert)
  65.     SetFlag(eVObjVFixed);
  66.     else
  67.     SetFlag(eVObjHFixed);
  68. }
  69.  
  70. GrCursor SplitArea::GetCursor(Point)
  71. {
  72.     return (dir == eVert) ? eCrsUpDownArrow : eCrsLeftRightArrow;
  73. }
  74.  
  75. Metric SplitArea::GetMinSize()
  76. {
  77.     return gLook->SashLayout()->GetMinSize(this);
  78. }
  79.  
  80. void SplitArea::Draw(Rectangle)
  81. {
  82.     gLook->SashLayout()->Adorn(this, contentRect, 0);
  83. }
  84.  
  85. Command *SplitArea::DoLeftButtonDownCommand(Point, Token, int)
  86. {
  87.     Point min, max;
  88.     ((SizeableExpander*)GetContainer())->GetStretchability(GetId(), min, max);
  89.     return new SplitMover(this, dir, min, max);
  90. }
  91.  
  92. //---- SizeableExpander ---------------------------------------------------------
  93.  
  94. NewMetaImpl0(SizeableExpander, Expander);
  95.  
  96. SizeableExpander::SizeableExpander(int id, Direction d, Point, VObject *va_(vop), ...): 
  97.                     Expander(id, d, gPoint0, (SeqCollection*)0)
  98. {
  99.     VObject *vp;
  100.     va_list ap;
  101.     va_start(ap,va_(vop));
  102.  
  103.     Add(va_(vop));
  104.     
  105.     for (int i= 0;; i++) {
  106.     if ((vp= va_arg(ap, VObject*)) == 0)
  107.         break;
  108.     Add(new SplitArea(i, d));
  109.     Add(vp);  
  110.     }
  111.     va_end(ap);
  112. }
  113.  
  114. void SizeableExpander::Control(int id, int part, void *val)
  115. {
  116.     Point rc= ColsRowsSize();
  117.     Direction dir= (rc.x > rc.y) ? eHor : eVert;
  118.  
  119.     if (part == cPartChangeSplit) {
  120.     Point dd;
  121.     dd[dir]= (*(Point*)val)[dir];
  122.         
  123.     for (int i= 0; i < 3; i++) {
  124.         VObject *vop= At(id*2+i);
  125.         switch(i) {
  126.         case 0:
  127.         vop->SetExtent(vop->GetExtent()+dd);
  128.         break;
  129.         case 1:
  130.         vop->SetOrigin(vop->GetOrigin()+dd); 
  131.         break;
  132.         case 2:    
  133.         vop->SetOrigin(vop->GetOrigin()+dd);
  134.         vop->SetExtent(vop->GetExtent()-dd);
  135.         break;
  136.         }
  137.         vop->ForceRedraw();
  138.     }
  139.     }
  140. }
  141.     
  142. void SizeableExpander::GetStretchability(int at, Point &min, Point &max)
  143. {
  144.     VObject *vop= At(at*2);
  145.     min= vop->GetMinSize().Extent() - vop->GetExtent();
  146.     
  147.     vop= At((at+1)*2);
  148.     max= vop->GetExtent() - vop->GetMinSize().Extent();
  149. }
  150.  
  151. void SizeableExpander::SetExtent(Point e)
  152. {
  153.     Iter next(MakeIterator());
  154.     register VObject *vop;
  155.     int d, div= 0, mod= 0, n= expandCnt();
  156.     Point newsize;
  157.     bool hfixed, vfixed;
  158.     Point rc= ColsRowsSize();
  159.     Direction dir= (rc.x > rc.y) ? eHor : eVert;
  160.     
  161.     if (GetExtent() == gPoint0) // ????
  162.     d= (e-GetMinSize().extent)[dir];
  163.     else
  164.     d= (e - GetExtent())[dir];
  165.     
  166.     VObject::SetExtent(e);
  167.     if (n > 0) {
  168.     div= d / n;
  169.     mod= d % n;
  170.     }
  171.     
  172.     while (vop= (VObject*) next()) {
  173.     vfixed= vop->TestFlag(eVObjVFixed);
  174.     hfixed= vop->TestFlag(eVObjHFixed);
  175.     if (vop->GetExtent() == gPoint0) // ????
  176.         newsize= vop->GetMinSize().extent;
  177.     else 
  178.         newsize= vop->GetExtent();
  179.     if (dir == eVert) {
  180.         if (!hfixed)
  181.         newsize.x= e.x;
  182.         if (!vfixed) {
  183.         newsize.y+= div;
  184.         if (mod > 0) {
  185.             newsize.y++;
  186.             mod--;
  187.         }
  188.         }
  189.     } else {
  190.         if (!vfixed)
  191.         newsize.y= e.y;
  192.         if (!hfixed) {
  193.         newsize.x+= div;
  194.         if (mod > 0) {
  195.             newsize.x++;
  196.             mod--;
  197.         }
  198.         }
  199.     }
  200.     vop->SetExtent(newsize);
  201.     }
  202. }
  203.